package liming.ai.code.v3;

import liming.ai.code.v3.core.ChatCore;
import liming.ai.code.v3.data.Context;
import liming.ai.code.v3.data.FileInfo;
import liming.ai.code.v3.data.JavaCode;
import liming.ai.code.v3.generator.HandlerCode;
import liming.tool.file.FileRW;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class AiMainTestV3 {
    static final String PACKAGE_NAME = "com.project.test";//包名

    static {
        FileRW.setDefaultWritingEncoding(FileRW.FileEncoding.UTF8);//设置默认编码
    }

    public static void main(String[] args) throws IOException {
        String prompt = "请生成一个用户管理模块，包含User类和UserService类,包名为" + PACKAGE_NAME;
        Context context = new Context(prompt);
        for (JavaCode javaCode : JavaCode.loads(ChatCore.valueToJson(ChatCore.chat(prompt, ChatCore.buildTechPrompt())).getJSONArray("classes"))) {//生成功能代码
            FileInfo fileData = new FileInfo(Context.PROJECT_PATH, javaCode.getPackageName(), javaCode.getClassName());
            load(fileData, javaCode, context);
        }
        FileInfo mainInfo = new FileInfo(Context.PROJECT_PATH, PACKAGE_NAME, "Main");
        JavaCode mainCode = new JavaCode(PACKAGE_NAME, "Main", new ArrayList<>(), "在这个类中生成一个 public static void main(String[] args) 方法,在这个方法中,根据上下文，对当前已生成的代码进行功能性测试");
        load(mainInfo, mainCode, context);
        Class<?> aClass = HandlerCode.loadClass(mainInfo);
        while (true)
            try {
                HandlerCode.doInvokeMethod(aClass, null, "main", new Object[]{new String[]{}});
                System.out.println("测试完毕");
                break;
            } catch (Exception e) {
                mainInfo.setException(e);
                handleException(mainInfo, context);
            }
        System.exit(0);
    }

    static void handleException(FileInfo fileData, Context context) throws IOException {
        if (fileData.getException() != null) {
            System.out.println("异常处理中:" + "\t" + fileData.getException() + "\t  " + fileData.toJson());
            JavaCode javaCode = new JavaCode(fileData.getPackageName(), fileData.getClassName(), null,
                    "md介绍文件:\n" + FileRW.readTextFile(fileData.getMdFile()) +
                            "\njava文件：\n" + FileRW.readTextFile(fileData.getJavaFile()) +
                            "\n异常:\n" + FileRW.getStackTrace(fileData.getException()));
            fileData.setException(null);
            load(fileData, javaCode, context);
        }
    }

    static void load(FileInfo fileData, JavaCode javaCode, Context context) throws IOException {
        List<JavaCode> think = JavaCode.think(javaCode, context);
        if (!think.isEmpty()) {
            l(fileData, think.remove(0), context);
            for (JavaCode code : think) {
                FileInfo fileInfo = new FileInfo(Context.PROJECT_PATH, code.getPackageName(), code.getClassName());
                load(fileInfo, code, context);
            }
        }

    }

    static void l(FileInfo fileData, JavaCode javaCode, Context context) throws IOException {
        System.out.println("java文件创建:" + HandlerCode.writeForFile(fileData, javaCode.getCode()));
        if (fileData.getException() != null) {
            handleException(fileData, context);
            return;
        }
        System.out.println("md文件写入" + HandlerCode.generateMdFile(fileData, javaCode.getMd()));
        if (fileData.getException() != null) {
            handleException(fileData, context);
            return;
        }

        System.out.println("class文件编译:" + HandlerCode.compileJavaFile(fileData, javaCode, "UTF-8"));
        if (fileData.getException() != null) {
            handleException(fileData, context);
            return;
        }
        context.addFile(fileData);
    }

}